home *** CD-ROM | disk | FTP | other *** search
/ Languguage OS 2 / Languguage OS II Version 10-94 (Knowledge Media)(1994).ISO / gnu / glibc108.zip / glibc108 / hurd / hurdioctl.c < prev    next >
C/C++ Source or Header  |  1994-05-21  |  5KB  |  220 lines

  1. /* ioctl commands which must be done in the C library.
  2. Copyright (C) 1994 Free Software Foundation, Inc.
  3. This file is part of the GNU C Library.
  4.  
  5. The GNU C Library is free software; you can redistribute it and/or
  6. modify it under the terms of the GNU Library General Public License as
  7. published by the Free Software Foundation; either version 2 of the
  8. License, or (at your option) any later version.
  9.  
  10. The GNU C Library is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  13. Library General Public License for more details.
  14.  
  15. You should have received a copy of the GNU Library General Public
  16. License along with the GNU C Library; see the file COPYING.LIB.  If
  17. not, write to the Free Software Foundation, Inc., 675 Mass Ave,
  18. Cambridge, MA 02139, USA.  */
  19.  
  20. #include <hurd.h>
  21. #include <hurd/fd.h>
  22. #include <sys/ioctl.h>
  23. #include <gnu-stabs.h>
  24.  
  25. /* Symbol set of ioctl handler lists.  This definition is here so that when
  26.    __ioctl refers to it, we will link in fionread et al (below).  */
  27.  
  28. const struct
  29.   {
  30.     size_t n;
  31.     struct ioctl_handler *v[0];
  32.   } _hurd_ioctl_handler_lists;
  33.  
  34. #include <fcntl.h>
  35.  
  36. /* Find out how many bytes may be read from FD without blocking.  */
  37.  
  38. static int
  39. fioctl (int fd,
  40.     int request,
  41.     int *arg)
  42. {
  43.   error_t err;
  44.  
  45.   *(volatile int *) arg = *arg;
  46.  
  47.   switch (request)
  48.     {
  49.     default:
  50.       err = EGRATUITOUS;
  51.       break;
  52.  
  53.     case FIONREAD:
  54.       err = HURD_DPORT_USE (fd, __io_readable (port, arg));
  55.       break;
  56.  
  57.     case FIONBIO:
  58.       err = HURD_DPORT_USE (fd, (*arg ?
  59.                  __io_set_some_openmodes :
  60.                  __io_clear_some_openmodes)
  61.                 (port, O_NONBLOCK));
  62.       break;
  63.  
  64.     case FIOASYNC:
  65.       err = HURD_DPORT_USE (fd, (*arg ?
  66.                  __io_set_some_openmodes :
  67.                  __io_clear_some_openmodes)
  68.                 (port, O_ASYNC));
  69.       break;
  70.  
  71.     case FIOSETOWN:
  72.       err = HURD_DPORT_USE (fd, __io_mod_owner (port, *arg));
  73.       break;
  74.  
  75.     case FIOGETOWN:
  76.       err = HURD_DPORT_USE (fd, __io_get_owner (port, arg));
  77.       break;
  78.     }
  79.  
  80.   return err ? __hurd_fail (err) : 0;
  81. }
  82.  
  83. _HURD_HANDLE_IOCTLS (fioctl, FIOGETOWN, FIONREAD);
  84.  
  85.  
  86. static int
  87. fioclex (int fd,
  88.      int request)
  89. {
  90.   int flag;
  91.  
  92.   switch (request)
  93.     {
  94.     default:
  95.       return __hurd_fail (EGRATUITOUS);
  96.     case FIOCLEX:
  97.       flag = FD_CLOEXEC;
  98.       break;
  99.     case FIONCLEX:
  100.       flag = 0;
  101.       break;
  102.     }
  103.  
  104.   return __fcntl (fd, F_SETFD, flag);
  105. }
  106. _HURD_HANDLE_IOCTLS (fioclex, FIOCLEX, FIONCLEX);
  107.  
  108. #include <hurd/term.h>
  109.  
  110. static void
  111. rectty_dtable (mach_port_t cttyid)
  112. {
  113.   int i;
  114.   
  115.   HURD_CRITICAL_BEGIN;
  116.   __mutex_lock (&_hurd_dtable_lock);
  117.  
  118.   for (i = 0; i < _hurd_dtablesize; ++i)
  119.     {
  120.       struct hurd_fd *const d = _hurd_dtable[i];
  121.       mach_port_t newctty;
  122.  
  123.       if (d == NULL)
  124.     /* Nothing to do for an unused descriptor cell.  */
  125.     continue;
  126.  
  127.       if (cttyid == MACH_PORT_NULL)
  128.     /* We now have no controlling tty at all.  */
  129.     newctty = MACH_PORT_NULL;
  130.       else
  131.     HURD_PORT_USE (&d->port,
  132.                ({ mach_port_t id;
  133.               /* Get the io object's cttyid port.  */
  134.               if (! __term_getctty (port, &id))
  135.                 {
  136.                   if (id == cttyid && /* Is it ours?  */
  137.                   /* Get the ctty io port.  */
  138.                   __term_become_ctty (port, _hurd_pid,
  139.                               _hurd_pgrp,
  140.                               _hurd_msgport,
  141.                               &newctty))
  142.                 /* XXX it is our ctty but the call failed? */
  143.                 newctty = MACH_PORT_NULL;
  144.                   __mach_port_deallocate
  145.                 (__mach_task_self (), (mach_port_t) id);
  146.                 }
  147.               else
  148.                 newctty = MACH_PORT_NULL;
  149.               0;
  150.             }));
  151.  
  152.       /* Install the new ctty port.  */
  153.       _hurd_port_set (&d->ctty, newctty);
  154.     }
  155.  
  156.   __mutex_unlock (&_hurd_dtable_lock);
  157.   HURD_CRITICAL_END;
  158. }
  159.  
  160.  
  161. /* Make FD be the controlling terminal.
  162.    This function is called for `ioctl (fd, TCIOSCTTY)'.  */
  163.  
  164. static int
  165. tiocsctty (int fd,
  166.        int request)        /* Always TIOCSCTTY.  */
  167. {
  168.   mach_port_t cttyid;
  169.   error_t err;
  170.  
  171.   /* Get FD's cttyid port, unless it is already ours.  */
  172.   err = HURD_DPORT_USE (fd,
  173.             ctty ? EADDRINUSE : __term_getctty (port, &cttyid));
  174.   if (err == EADDRINUSE)
  175.     /* FD is already the ctty.  Nothing to do.  */
  176.     return 0;
  177.   else if (err)
  178.     return __hurd_fail (err);
  179.  
  180.   /* Make it our own.  */
  181.   _hurd_port_set (&_hurd_ports[INIT_PORT_CTTYID], cttyid); /* Consumes ref.  */
  182.  
  183.   /* Reset all the ctty ports in all the descriptors.  */
  184.   __USEPORT (CTTYID, (rectty_dtable (port), 0));
  185.  
  186.   return 0;
  187. }
  188. _HURD_HANDLE_IOCTL (tiocsctty, TIOCSCTTY);
  189.  
  190. /* Dissociate from the controlling terminal.  */
  191.  
  192. static int
  193. tiocnotty (int fd,
  194.        int request)        /* Always TIOCNOTTY.  */
  195. {
  196.   mach_port_t fd_cttyid;
  197.   error_t err;
  198.  
  199.   if (err = HURD_DPORT_USE (fd, __term_getctty (port, &fd_cttyid)))
  200.     return __hurd_fail (err);
  201.  
  202.   if (__USEPORT (CTTYID, port != fd_cttyid))
  203.     err = EINVAL;
  204.  
  205.   __mach_port_deallocate (__mach_task_self (), fd_cttyid);
  206.  
  207.   if (err)
  208.     return __hurd_fail (err);
  209.  
  210.   /* Clear our cttyid port cell.  */
  211.   _hurd_port_set (&_hurd_ports[INIT_PORT_CTTYID], MACH_PORT_NULL);
  212.  
  213.   /* Reset all the ctty ports in all the descriptors.  */
  214.                 
  215.   __USEPORT (CTTYID, (rectty_dtable (MACH_PORT_NULL), 0));
  216.  
  217.   return 0;
  218. }
  219. _HURD_HANDLE_IOCTL (tiocnotty, TIOCNOTTY);
  220.